#ifndef GEN_LIST_H
#define GEN_LIST_H
namespace Apo
{



template <class Type> class queue;
template <class Type> class QueueItem
{
public:
	friend class queue<Type>;
	QueueItem(const Type &t):item(t),next(0){}
	Type item;
	QueueItem *next;
};

template <class Type> class queue
{
public:
	QueueItem<Type> *head;
	QueueItem<Type> *tail;
	void destory();
	void copy_elems(const queue &);

	queue():head(0),tail(0){}
	queue(const queue &Q):head(0),tail(0)
	{
		copy_elems(Q);
	}
	queue & operator = (const queue &);
	~queue()
	{
		destory();
	}

	Type &front() 
	{
		return head->item;
	}

	const Type &front ()const
	{
		return head->item;
	}
	void push_back(const Type &);
	void pop_front();
	bool empty() const
	{
		return head==0;
	}
};

template <class Type>
void queue<Type>::destory()
{
	while (!empty())
		pop_front();
}
template <class Type>
void queue<Type>::pop_front()
{
	QueueItem<Type> *p=head;
	// cout << p->item<<endl;
	head =head->next;
	delete p;
}

template <class Type>
void queue<Type>::push_back(const Type &val)
{
	QueueItem<Type> *pt =new QueueItem<Type>(val);
	if( empty()){
		head =tail =pt;
		//  cout << tail->item<<endl;
	}
	else
	{
		// cout << pt->item<<endl;
		tail->next = pt;
		tail =pt;
	}
}
template <class Type>
void queue<Type>::copy_elems(const queue &orig)
{
	for( QueueItem<Type> *pt =orig.head; pt; pt=pt->next)
		push_back(pt->item);
}

template <class Type>
queue<Type> & queue<Type>::operator = (const queue &orig)
{
	queue<Type> *queue=new queue<Type>;
	for( QueueItem<Type> *pt =orig.head; pt; pt=pt->next)
		queue.push_back(pt->item);

	return *queue;
}


}


#endif



